<template>
  <div class="search-table_container">
    <div class="search_content">
      <Form
        ref="form"
        v-bind="formConfig"
        :triggerValidate="false"
        :submitText="$t('common.Search')"
        v-model="formData"
        @submit="handleSearch"
        @expandChange="handleExpandChange"
      />
    </div>
    <div class="table_content">
      <Table
        ref="table"
        v-bind="attrs"
        :data="attrs.fetchData ? null : sourceData"
      />
    </div>
  </div>
</template>

<script setup>
import Table from "../Table/index.vue";
import Form from "../Form/index.vue";
import { ref, useTemplateRef, useAttrs, computed, toRaw } from "vue";
import { useI18n } from "vue-i18n";
import { datePickTypes } from "element-plus";
defineOptions({
  name: "SearchTable",
  inheritAttrs: false,
});
const attrs = useAttrs();
const { t } = useI18n();
const formData = ref({});
const tabelRef = useTemplateRef("table");
const formRef = useTemplateRef("form");
const emits = defineEmits(["search"]);
const props = defineProps({
  formItems: { type: [Array, null], default: null },
  // 可搜索字段 默认 null 为全部 在没有传递formItems情况下
  searchFields: { type: [Array, null], default: null },
  // 精确搜索字段 默认全部模糊搜索
  exactSearchFields: { type: Array, default: () => [] },
  // 自定义搜索
  customSearch: { type: [Function, null], default: null },
});

const formConfig = computed(() => {
  if (props.formConfig) {
    return { formItems: props.formItems };
  }
  const columns = attrs.columns || [];
  const config = columns
    .filter((v) =>
      props.searchFields ? props.searchFields.includes(v.prop) : true
    )
    .map((v) => {
      const c = {
        type: v.fieldType || "input",
        prop: v.prop,
        label: v.label,
      };
      if ("dictionary" in v) {
        c.dictionary = v.dictionary;
      }
      return c;
    });
  return { formItems: config };
});
const filterData = ref([]);
const sourceData = computed(() => {
  return filterData.value.length > 0 ? filterData.value : attrs.data;
});

function handleSearch() {
  formRef.value.formInstance.validate((validate) => {
    if (validate) {
      const searchParams = toRaw(formData.value);
      if (attrs.fetchData) {
        tabelRef.value.fetchData(true, searchParams);
        emits("search", searchParams);
        return;
      }
      const originalData = attrs.data || [];
      // if (!是否筛选) {
      //   return;
      // }
      filterData.value = originalData.filter((item) =>
        props.customSearch
          ? props.customSearch(item, searchParams)
          : Object.keys(searchParams).every((key) => {
              const searchValue = searchParams[key];
              const itemValue = item[key];
              const itemConfig = formConfig.value.formItems.find(
                (item) => item.prop === key
              );

              const fn = getFieldSearch(itemConfig, key);
              return fn(itemValue, searchValue);
            })
      );
      emits("search", searchParams);
    }
  });
}
// 根据表单配置字段类型生成搜索匹配函数
function getFieldSearch(itemConfig, field) {
  const fieldType = itemConfig.type;
  const isExact = props.exactSearchFields.includes(field); // 是否精确搜索
  if (fieldType === "input") {
    return isExact
      ? (originaValue, searchValue) => originaValue === searchValue
      : (originaValue, searchValue) => originaValue.includes(searchValue);
  } else if (fieldType === "select" || fieldType === "vSelect") {
    const isMultiple = itemConfig.componentProps?.multiple;
    return isMultiple
      ? (originaValue, searchValue) =>
          searchValue && searchValue.length
            ? searchValue.includes(originaValue)
            : true
      : (originaValue, searchValue) => originaValue === searchValue;
  } else if (datePickTypes.includes(fieldType)) {
    if (fieldType.endsWith("range")) {
      // 范围
      return (originaValue, searchValue) => {
        const [start, end] = searchValue;
        if (!start || !end) {
          return true;
        } else {
          const date = new Date(originaValue).getTime();
          const startDate = new Date(start).getTime();
          const endDate = new Date(end).getTime();
          return date >= startDate && date <= endDate;
        }
      };
    } else {
      return isExact
        ? (originaValue, searchValue) =>
            new Date(originaValue).getTime() === new Date(searchValue).getTime()
        : (originaValue, searchValue) =>
            new Date(originaValue).getTime() >= new Date(searchValue).getTime();
    }
  } else if (fieldType === "number") {
    return isExact
      ? (originaValue, searchValue) => originaValue === searchValue
      : (originaValue, searchValue) => originaValue >= searchValue;
  } else if (fieldType === "radio") {
    return (originaValue, searchValue) => originaValue === searchValue;
  } else if (fieldType === "checkbox") {
    return (originaValue, searchValue) => searchValue.includes(originaValue);
  } else if (fieldType === "switch") {
    return (originaValue, searchValue) =>
      Boolean(originaValue) === Boolean(searchValue);
  } else {
    return (originaValue, searchValue) =>
      String(originaValue).includes(String(searchValue));
  }
}

function handleExpandChange() {
  tabelRef.value.resize();
}
</script>

<style scoped>
.search-table_container {
  display: flex;
  flex-direction: column;
}
.table_content {
  flex: 1;
}
.search_content {
  background-color: var(--bg-primary);
  border-radius: var(--baseBorderRadius);
  padding: 0 20px;
  margin-bottom: 10px;
}
</style>
